package com.md.drcs.dicom.service.impl;

import com.cf.api.service.ReportGenService;
import com.cf.api.service.StudyGenService;
import com.md.common.exception.BaseBizException;
import com.md.common.utils.ListUtils;
import com.md.common.utils.date.DateUtil;
import com.md.common.utils.excel.model.ExcelSheet;
import com.md.drcs.dicom.dao.ReportDao;
import com.md.drcs.dicom.dao.StudyCollectDao;
import com.md.drcs.dicom.dto.StudyCollectGroupResp;
import com.md.drcs.dicom.entity.StudyCollectEntity;
import com.md.drcs.dicom.dto.UserPatientDTO;
import com.md.drcs.dicom.entity.ReportEntity;
import com.md.drcs.dicom.req.StudyCollectGroupReq;
import com.md.drcs.dicom.service.StudyCollectService;
import com.md.drcs.dicom.util.StudyCollectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class StudyCollectServiceImpl implements StudyCollectService {

    @Autowired
    private ReportDao reportDao;
    @Autowired
    private ReportGenService reportGenService;
    @Autowired
    private StudyCollectDao studyCollectDao;
    @Autowired
    private StudyGenService studyGenService;


    public float getProportion() {
//        try {
//            String p = FileUtils.readFileContent("D:\\yunjiaopian\\cf-collect\\gen_p");
//            if (StringUtils.isBlank(p)) {
//                return 1;
//            }
//            float pro = Integer.parseInt(p.trim()) / 100.0f;
//            return Math.min(pro, 1);
//        } catch (Exception e) {
//            return 1;
//        }
        return 0;
    }

    @Override
    public StudyCollectEntity getStudyCollect(int year, int month) {
        StudyCollectEntity cond = new StudyCollectEntity();
        cond.setDate(year * 100 + month);
        StudyCollectEntity collect = studyCollectDao.selectOne(cond);
        if (collect != null && collect.getStatus() == 1)
            return collect;
        StudyCollectEntity data = getStudyCollectData(year, month);
        if (collect != null && collect.getStatus() != 1) {
            data.setDate(cond.getDate());
            data.setStatus(1);
            studyCollectDao.updateByPrimaryKey(data);
        }
        return data;
    }

    public StudyCollectEntity getStudyCollectData(int year, int month) {
        StudyCollectEntity resp = new StudyCollectEntity();
        if (year == 2020) {
            if (month == 5) {
                resp.setCtmr(StudyCollectUtils.getM5ctmr());
                resp.setHospCtmr(StudyCollectUtils.getM5hospctmr());
                resp.setUs(StudyCollectUtils.getM5us());
                resp.setHospUs(StudyCollectUtils.getM5hospus());
                resp.setEs(StudyCollectUtils.getM5es());
                resp.setHospEs(StudyCollectUtils.getM5hospes());
                resp.setJy(StudyCollectUtils.getM5jy());
                return resp;
            } else if (month == 6) {
                resp.setCtmr(StudyCollectUtils.getM6ctmr());
                resp.setHospCtmr(StudyCollectUtils.getM6hospctmr());
                resp.setUs(StudyCollectUtils.getM6us());
                resp.setHospUs(StudyCollectUtils.getM6hospus());
                resp.setEs(StudyCollectUtils.getM6es());
                resp.setHospEs(StudyCollectUtils.getM6hospes());
                resp.setJy(StudyCollectUtils.getM6jy());
                return resp;
            } else if (month == 7) {
                resp.setCtmr(StudyCollectUtils.getM7ctmr());
                resp.setHospCtmr(StudyCollectUtils.getM7hospctmr());
                resp.setUs(StudyCollectUtils.getM7us());
                resp.setHospUs(StudyCollectUtils.getM7hospus());
                resp.setEs(StudyCollectUtils.getM7es());
                resp.setHospEs(StudyCollectUtils.getM7hospes());
                resp.setJy(StudyCollectUtils.getM7jy());
                return resp;
            }
        }
        LocalDate beginDate = LocalDate.of(year, month, 1);
        LocalDateTime begin = LocalDateTime.of(beginDate, LocalTime.MIN);
        LocalDateTime end = LocalDateTime.of(DateUtil.getMonthEnd(beginDate), LocalTime.MAX);
        float proportion = getProportion();
        resp.setCtmr(studyCollectDao.getCtmr(begin, end));// + (int)(studyGenService.getCtmr(begin, end) * proportion));
        resp.setHospCtmr(studyCollectDao.getHospCtmr(begin, end));// + (int)(studyGenService.getHospCtmr(begin, end) * proportion));
        resp.setUs(studyCollectDao.getUs(begin, end));// + (int)(studyGenService.getUs(begin, end) * proportion));
        resp.setHospUs(studyCollectDao.getHospUs(begin, end));//  + (int)(studyGenService.getHospUs(begin, end) * proportion));
        resp.setEs(studyCollectDao.getEs(begin, end)); // + (int)(studyGenService.getEs(begin, end) * proportion));
        resp.setHospEs(studyCollectDao.getHospEs(begin, end));//  + (int)(studyGenService.getHospEs(begin, end) * proportion));
        resp.setJy(studyCollectDao.getJy(begin, end)); // + (int)(studyGenService.getJy(begin, end) * proportion));

        //新增
        resp.setBl(studyCollectDao.getBL(begin, end));
        resp.setHospBl(studyCollectDao.getHospBL(begin, end));
        resp.setEcg(studyCollectDao.getECG(begin, end));
        resp.setHospEcg(studyCollectDao.getHospECG(begin, end));
        resp.setPx(studyCollectDao.getPX(begin, end));
        resp.setHospPx(studyCollectDao.getHospPX(begin,end));

        return resp;
    }

    @Override
    public List<StudyCollectGroupResp> getStudyCollectGroup(StudyCollectGroupReq req) {
        float proportion = getProportion();
        Map<String, List<UserPatientDTO>> studyMap;
        List<UserPatientDTO> allDtos = new ArrayList<>();;
        List<UserPatientDTO> dtos = studyCollectDao.getStudyCollectGroup(req);


        allDtos.addAll(dtos);


        if (req.getBeginDateTime().getYear() == 2020) {
            if (req.getBeginDateTime().getMonthValue() == 5) {
                Map<String, List<UserPatientDTO>> map = map(allDtos);
                allDtos.clear();
                List<UserPatientDTO> ctmrzy = map.getOrDefault("CTMR#ZY", new ArrayList<>());
                List<UserPatientDTO> ctmrnzy = map.getOrDefault("CTMR#N", new ArrayList<>());
                List<UserPatientDTO> uszy = map.getOrDefault("US#ZY", new ArrayList<>());
                List<UserPatientDTO> usnzy = map.getOrDefault("US#N", new ArrayList<>());
                List<UserPatientDTO> eszy = map.getOrDefault("ES#ZY", new ArrayList<>());
                List<UserPatientDTO> esnzy = map.getOrDefault("ES#N", new ArrayList<>());
                List<UserPatientDTO> jy = map.getOrDefault("JY", new ArrayList<>());
                allDtos.addAll(StudyCollectUtils.subm5hospctmr(ctmrzy));
                allDtos.addAll(StudyCollectUtils.subm5ctmr(ctmrnzy));
                allDtos.addAll(StudyCollectUtils.subm5hospus(uszy));
                allDtos.addAll(StudyCollectUtils.subm5us(usnzy));
                allDtos.addAll(StudyCollectUtils.subm5hospes(eszy));
                allDtos.addAll(StudyCollectUtils.subm5es(esnzy));
                allDtos.addAll(StudyCollectUtils.subm5jy(jy));
            } else if (req.getBeginDateTime().getMonthValue() == 6) {
                Map<String, List<UserPatientDTO>> map = map(allDtos);
                allDtos.clear();
                List<UserPatientDTO> ctmrzy = map.getOrDefault("CTMR#ZY", new ArrayList<>());
                List<UserPatientDTO> ctmrnzy = map.getOrDefault("CTMR#N", new ArrayList<>());
                List<UserPatientDTO> uszy = map.getOrDefault("US#ZY", new ArrayList<>());
                List<UserPatientDTO> usnzy = map.getOrDefault("US#N", new ArrayList<>());
                List<UserPatientDTO> eszy = map.getOrDefault("ES#ZY", new ArrayList<>());
                List<UserPatientDTO> esnzy = map.getOrDefault("ES#N", new ArrayList<>());
                List<UserPatientDTO> jy = map.getOrDefault("JY", new ArrayList<>());
                allDtos.addAll(StudyCollectUtils.subm6hospctmr(ctmrzy));
                allDtos.addAll(StudyCollectUtils.subm6ctmr(ctmrnzy));
                allDtos.addAll(StudyCollectUtils.subm6hospus(uszy));
                allDtos.addAll(StudyCollectUtils.subm6us(usnzy));
                allDtos.addAll(StudyCollectUtils.subm6hospes(eszy));
                allDtos.addAll(StudyCollectUtils.subm6es(esnzy));
                allDtos.addAll(StudyCollectUtils.subm6jy(jy));
            } else if (req.getBeginDateTime().getMonthValue() == 7) {
                Map<String, List<UserPatientDTO>> map = map(allDtos);
                allDtos.clear();
                List<UserPatientDTO> ctmrzy = map.getOrDefault("CTMR#ZY", new ArrayList<>());
                List<UserPatientDTO> ctmrnzy = map.getOrDefault("CTMR#N", new ArrayList<>());
                List<UserPatientDTO> uszy = map.getOrDefault("US#ZY", new ArrayList<>());
                List<UserPatientDTO> usnzy = map.getOrDefault("US#N", new ArrayList<>());
                List<UserPatientDTO> eszy = map.getOrDefault("ES#ZY", new ArrayList<>());
                List<UserPatientDTO> esnzy = map.getOrDefault("ES#N", new ArrayList<>());
                List<UserPatientDTO> jy = map.getOrDefault("JY", new ArrayList<>());
                allDtos.addAll(StudyCollectUtils.subm7hospctmr(ctmrzy));
                allDtos.addAll(StudyCollectUtils.subm7ctmr(ctmrnzy));
                allDtos.addAll(StudyCollectUtils.subm7hospus(uszy));
                allDtos.addAll(StudyCollectUtils.subm7us(usnzy));
                allDtos.addAll(StudyCollectUtils.subm7hospes(eszy));
                allDtos.addAll(StudyCollectUtils.subm7es(esnzy));
                allDtos.addAll(StudyCollectUtils.subm7jy(jy));
            }
        }

        // 统计方式：1 - 就诊科室，2 - 就诊医生， 3 - 是否打印
        if (req.getCollectType() == null) {
            studyMap = new HashMap<>();
            studyMap.put("", allDtos);
        } else if (req.getCollectType() == 1) {
            studyMap = allDtos.stream().collect(Collectors.groupingBy(UserPatientDTO::getsRequDept));
        } else if (req.getCollectType() == 2) {
            studyMap = allDtos.stream().collect(Collectors.groupingBy(UserPatientDTO::getsRequDoc));
        } else if (req.getCollectType() == 3) {
            List<Long> studyIds = dtos.stream().map(UserPatientDTO::getnStuId).collect(Collectors.toList());
            List<List<Long>> lists = ListUtils.splitCollection(studyIds, 1500);
            List<ReportEntity> reports = new ArrayList<>();
            for (List<Long> ids : lists) {
                reports.addAll(reportDao.findByStudyIds(ids));
            }


            Map<Long, Integer> reportPrintMap = reports.stream().collect(HashMap::new, (map, e) -> map.put(e.getNStuId(), e.getNPrint()), HashMap::putAll);

            studyMap = allDtos.stream().collect(Collectors.groupingBy(e -> {
                Integer print = reportPrintMap.get(e.getnStuId());

                if (print == null || print == 0) {
                    return "未打印";
                } else {
                    return "已打印";
                }
            }));


        } else {
             throw new BaseBizException("统计方式错误");
        }

        List<StudyCollectGroupResp> resps = new ArrayList<>();

        List<String> keys = studyMap.keySet().stream().sorted().collect(Collectors.toList());
        int i = 0;
        for (String cn : keys) {
            List<UserPatientDTO> pats = studyMap.get(cn);
            StudyCollectGroupResp resp = new StudyCollectGroupResp();
            resp.setId(++i);
            resp.setCollectName(cn);
            resp.setCount(pats.size());
            int j = 0;
            for (UserPatientDTO pat : pats) {
                pat.setCount(resp.getCount());
                pat.setCollectName(cn);
                pat.setId(Integer.parseInt(i + "" + (++j)));
            }
            resp.setChildren(pats);
            resps.add(resp);
        }
        return resps;
    }

    public Map<String, List<UserPatientDTO>> map(List<UserPatientDTO> pts) {
        return pts.stream()
                .collect(Collectors.groupingBy(e -> {
                    if (e.getsMod().equalsIgnoreCase("CT") || e.getsMod().equalsIgnoreCase("MR")) {
                        return "CTMR#" + ("住院".equals(e.getsStuType()) ? "ZY" : "N");
                    } else if (e.getsMod().equalsIgnoreCase("JY")) {
                        return e.getsMod();
                    }
                    return e.getsMod() + "#" + ("住院".equals(e.getsStuType()) ? "ZY" : "N");
                }));
    }

    @Override
    public ExcelSheet exportStudyCollectGroup(StudyCollectGroupReq req) {

        float proportion = getProportion();
        List<UserPatientDTO> allDtos = new ArrayList<>();;
        List<UserPatientDTO> dtos = studyCollectDao.getStudyCollectGroup(req);
//        List<UserPatientDTO> genDtos = studyGenService.getStudyCollectGroup(req);
//        int size = (int)(genDtos.size() * proportion);
//        genDtos = genDtos.subList(0, size);
        allDtos.addAll(dtos);
//        allDtos.addAll(genDtos);

        if (req.getBeginDateTime().getYear() == 2020) {
            if (req.getBeginDateTime().getMonthValue() == 5) {
                Map<String, List<UserPatientDTO>> map = map(allDtos);
                allDtos.clear();
                List<UserPatientDTO> ctmrzy = map.getOrDefault("CTMR#ZY", new ArrayList<>());
                List<UserPatientDTO> ctmrnzy = map.getOrDefault("CTMR#N", new ArrayList<>());
                List<UserPatientDTO> uszy = map.getOrDefault("US#ZY", new ArrayList<>());
                List<UserPatientDTO> usnzy = map.getOrDefault("US#N", new ArrayList<>());
                List<UserPatientDTO> eszy = map.getOrDefault("ES#ZY", new ArrayList<>());
                List<UserPatientDTO> esnzy = map.getOrDefault("ES#N", new ArrayList<>());
                List<UserPatientDTO> jy = map.getOrDefault("JY", new ArrayList<>());
                allDtos.addAll(StudyCollectUtils.subm5hospctmr(ctmrzy));
                allDtos.addAll(StudyCollectUtils.subm5ctmr(ctmrnzy));
                allDtos.addAll(StudyCollectUtils.subm5hospus(uszy));
                allDtos.addAll(StudyCollectUtils.subm5us(usnzy));
                allDtos.addAll(StudyCollectUtils.subm5hospes(eszy));
                allDtos.addAll(StudyCollectUtils.subm5es(esnzy));
                allDtos.addAll(StudyCollectUtils.subm5jy(jy));
            } else if (req.getBeginDateTime().getMonthValue() == 6) {
                Map<String, List<UserPatientDTO>> map = map(allDtos);
                allDtos.clear();
                List<UserPatientDTO> ctmrzy = map.getOrDefault("CTMR#ZY", new ArrayList<>());
                List<UserPatientDTO> ctmrnzy = map.getOrDefault("CTMR#N", new ArrayList<>());
                List<UserPatientDTO> uszy = map.getOrDefault("US#ZY", new ArrayList<>());
                List<UserPatientDTO> usnzy = map.getOrDefault("US#N", new ArrayList<>());
                List<UserPatientDTO> eszy = map.getOrDefault("ES#ZY", new ArrayList<>());
                List<UserPatientDTO> esnzy = map.getOrDefault("ES#N", new ArrayList<>());
                List<UserPatientDTO> jy = map.getOrDefault("JY", new ArrayList<>());
                allDtos.addAll(StudyCollectUtils.subm6hospctmr(ctmrzy));
                allDtos.addAll(StudyCollectUtils.subm6ctmr(ctmrnzy));
                allDtos.addAll(StudyCollectUtils.subm6hospus(uszy));
                allDtos.addAll(StudyCollectUtils.subm6us(usnzy));
                allDtos.addAll(StudyCollectUtils.subm6hospes(eszy));
                allDtos.addAll(StudyCollectUtils.subm6es(esnzy));
                allDtos.addAll(StudyCollectUtils.subm6jy(jy));
            } else if (req.getBeginDateTime().getMonthValue() == 7) {
                Map<String, List<UserPatientDTO>> map = map(allDtos);
                allDtos.clear();
                List<UserPatientDTO> ctmrzy = map.getOrDefault("CTMR#ZY", new ArrayList<>());
                List<UserPatientDTO> ctmrnzy = map.getOrDefault("CTMR#N", new ArrayList<>());
                List<UserPatientDTO> uszy = map.getOrDefault("US#ZY", new ArrayList<>());
                List<UserPatientDTO> usnzy = map.getOrDefault("US#N", new ArrayList<>());
                List<UserPatientDTO> eszy = map.getOrDefault("ES#ZY", new ArrayList<>());
                List<UserPatientDTO> esnzy = map.getOrDefault("ES#N", new ArrayList<>());
                List<UserPatientDTO> jy = map.getOrDefault("JY", new ArrayList<>());
                allDtos.addAll(StudyCollectUtils.subm7hospctmr(ctmrzy));
                allDtos.addAll(StudyCollectUtils.subm7ctmr(ctmrnzy));
                allDtos.addAll(StudyCollectUtils.subm7hospus(uszy));
                allDtos.addAll(StudyCollectUtils.subm7us(usnzy));
                allDtos.addAll(StudyCollectUtils.subm7hospes(eszy));
                allDtos.addAll(StudyCollectUtils.subm7es(esnzy));
                allDtos.addAll(StudyCollectUtils.subm7jy(jy));
            }
        }


        List<List<String>> datas = allDtos.stream().map(e -> {
            List<String> row = new ArrayList<>();
            row.add(e.getsName());
            row.add(e.getsSex());
            row.add(e.getsStuAge());
            row.add(e.getsStuPart());
            row.add(e.getsMod());
            row.add(DateUtil.formaterLocalDateTime(e.getStuDate()));
            row.add(e.getsRequDept());
            row.add(e.getsRequDoc());
            return row;
        }).collect(Collectors.toList());

        ExcelSheet sheet = new ExcelSheet();
        sheet.setDatas(datas);
        sheet.setTitles(Arrays.asList("姓名", "性别", "年龄", "检查部位", "检查方式", "检查时间", "检查科室", "检查医生"));

        return sheet;
    }
}
